package com.daiziru.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.daiziru.VO.PostVO;
import com.daiziru.entity.MPost;
import com.daiziru.search.model.PostDocument;
import com.daiziru.search.mq.PostMqIndexMessage;
import com.daiziru.search.repository.PostRepository;
import com.daiziru.service.MPostService;
import com.daiziru.service.SearchService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 作者：無言
 * 时间：2022/12/20 17:35
 * 描述：永无BUG
 */

@Slf4j
@Service
public class SearchServiceImpl implements SearchService {


    @Autowired
    PostRepository postRepository;

    @Autowired
    MPostService postService;


    /**
     * 文章数据初始化到es中
     * @param records 所有的文章信息
     * @return
     */
    @Override
    public int initEsData(List<PostVO> records) {
        if(records == null || records.isEmpty()) {
            return 0;
        }
        List<PostDocument> documents = new ArrayList<>();
        for(PostVO vo : records) {
            // 映射转换
            PostDocument postDocument = new PostDocument();
            BeanUtils.copyProperties(vo, postDocument);
            documents.add(postDocument);
        }
        //数据存储到到es的post索引中
        postRepository.saveAll(documents);
        return documents.size();
    }


    /**
     * PostRepository继承了 ->ElasticsearchRepository -> crudRepository
     * Repository（es）是使用的分页查询等是jpa的（jpa继承crudRepository），会存在转化,下面文章可以了解
     * https://blog.csdn.net/weixin_42707397/article/details/109579186
     * @param page  mybatis-plus的page
     * @param keyword 要搜索的关键字
     * @return
     */
    @Override
    public IPage search(Page page, String keyword) {
        //1、mybatis-plus的page -> jpa可以使用的page信息
        Long current = page.getCurrent() - 1; //减一是因为jpa的page当前页是从0开始的
        Long size = page.getSize();
        PageRequest pageable= PageRequest.of(current.intValue(), size.intValue());
        //2、通过curdRepository的api实现es数据的搜索
        MultiMatchQueryBuilder builder = QueryBuilders.multiMatchQuery(keyword, "title", "authorName", "categoryName");
        org.springframework.data.domain.Page<PostDocument> searchResult = postRepository.search(builder,pageable);
        //3、将上面得到的jpa分页信息转化为mybatis-plus的分页信息
        IPage pageData = new Page(page.getCurrent(), page.getSize(), searchResult.getTotalElements());
        pageData.setRecords(searchResult.getContent());
        return pageData;
    }

    /**
     * 同步修改或者新增的文章到es中
     * @param message
     */
    @Override
    public void createOrUpdateIndex(PostMqIndexMessage message) {
        Long postId = message.getPostId();
        //数据库查询新增或者修改文章信息
        PostVO postVO = postService.selectOnePost(new QueryWrapper<MPost>().eq("p.id", postId));
        PostDocument postDocument = new PostDocument();
        BeanUtils.copyProperties(postVO, postDocument);
        //更新内容到es
        postRepository.save(postDocument);
        log.info("es 索引更新成功！ ---> {}", postDocument.toString());
    }

    /**
     * 删除es中的文章数据
     * @param message
     */
    @Override
    public void removeIndex(PostMqIndexMessage message) {
        Long postId = message.getPostId();
        postRepository.deleteById(postId);
        log.info("es 索引删除成功！ ---> {}", message.toString());
    }
}
